package com.hcb.tonguetiphealth.util; 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.util.Map;

import android.os.Handler;
import android.os.Message;

import com.hcb.tonguetiphealth.model.FormFile;

/**
 * 上传文件到服务器
 * 
 * @author Administrator
 *
 */
public class SocketHttpRequester {
	private Handler handler ;
	private int alreadyUploaded = 0;
	private int totalFileSize = 0;
    /**
     * 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:
     * @param path 上传路径(注：避免使用localhost或127.0.0.1这样的路径测试，因为它会指向手机模拟器，你可以使用http://www.iteye.cn或http://192.168.1.101:8083这样的路径测试)
     * @param params 请求参数 key为参数名,value为参数值
     * @param file 上传文件
     */
    public String post(String path, Map<String, String> params, FormFile[] files) throws Exception{
        final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线
        final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志
        
        int fileDataLength = 0;
        for(FormFile uploadFile : files){//得到文件类型数据的总长度
        	if (uploadFile!=null && uploadFile.getFile() !=null) {
                StringBuilder fileExplain = new StringBuilder();
                fileExplain.append("--");
                fileExplain.append(BOUNDARY);
                fileExplain.append("\r\n");
                fileExplain.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
                fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
                fileExplain.append("\r\n");
                fileDataLength += fileExplain.length();
               if(uploadFile.getInStream()!=null){
                   fileDataLength += uploadFile.getFile().length();
                }else{
                    fileDataLength += uploadFile.getData().length;
                }
			}

        }
        setTotalFileSize(fileDataLength);//文件总大小
        Handler handler = getHandler();
        if(getHandler() != null){
      	    Message msg = handler.obtainMessage(); 
      	  //  msg.what = MessageWhat.MESSAGE_UPLOAD_START;//文件开始传输消息
      	    msg.sendToTarget();
         }
        StringBuilder textEntity = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型参数的实体数据
            textEntity.append("--");
            textEntity.append(BOUNDARY);
            textEntity.append("\r\n");
            textEntity.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
            textEntity.append(entry.getValue());
            textEntity.append("\r\n");
        }
        //计算传输给服务器的实体数据总长度
        int dataLength = textEntity.toString().getBytes().length + fileDataLength +  endline.getBytes().length;
        
        URL url = new URL(path);
        int port = url.getPort()==-1 ? 80 : url.getPort();
        Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);           
        OutputStream outStream = socket.getOutputStream();
        //下面完成HTTP请求头的发送
        String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";
        outStream.write(requestmethod.getBytes());
        String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";
        outStream.write(accept.getBytes());
        String language = "Accept-Language: zh-CN\r\n";
        outStream.write(language.getBytes());
        String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ "\r\n";
        outStream.write(contenttype.getBytes());
        String contentlength = "Content-Length: "+ dataLength + "\r\n";
        outStream.write(contentlength.getBytes());
        String alive = "Connection: Keep-Alive\r\n";
        outStream.write(alive.getBytes());
        String host = "Host: "+ url.getHost() +":"+ port +"\r\n";
        outStream.write(host.getBytes());
        //写完HTTP请求头后根据HTTP协议再写一个回车换行
        outStream.write("\r\n".getBytes());
        //把所有文本类型的实体数据发送出来
        outStream.write(textEntity.toString().getBytes());           
        //把所有文件类型的实体数据发送出来
        for(FormFile uploadFile : files){
        	if (uploadFile!=null && uploadFile.getFile() !=null) {
        		 StringBuilder fileEntity = new StringBuilder();
                 fileEntity.append("--");
                 fileEntity.append(BOUNDARY);
                 fileEntity.append("\r\n");
                 fileEntity.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
                 fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
                 outStream.write(fileEntity.toString().getBytes());
                 if(uploadFile.getInStream()!=null){
                     byte[] buffer = new byte[1024];
                     int len = 0;
                     setAlreadyUploaded(0);
                     while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1){
                         outStream.write(buffer, 0, len);
                         setAlreadyUploaded(getAlreadyUploaded()+len);//已经上传文件大小
                         if(handler != null){
                      	    Message msg = handler.obtainMessage(); 
                  //    	    msg.what = MessageWhat.MESSAGE_UPLOAD_SUCCESS_PER;
                      	    msg.sendToTarget();
                         }
                     }
                     uploadFile.getInStream().close();
                 }else{
                     outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);
                 }
                 outStream.write("\r\n".getBytes());
        	}
        }
        
        //下面发送数据结束标志，表示数据已经结束
        outStream.write(endline.getBytes()); 
        if(handler != null){
      	    Message msg = handler.obtainMessage(); 
      //	    msg.what = MessageWhat.MESSAGE_UPLOAD_END;
      	    msg.sendToTarget();
         }
        InputStream is = socket.getInputStream(); 
        String returnString = convertStreamToString(is);
        
//        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//        if(reader.readLine().indexOf("200")==-1){//读取web服务器返回的数据，判断请求码是否为200，如果不是200，代表请求失败
//            return false;
//        }
        outStream.flush();
        outStream.close();
//        reader.close();
        socket.close();
        return returnString;
    }
    /**
     * 为了将InputStream转换成String我们使用函数BufferedReader.readLine().
     * 我们迭代调用BufferedReader直到其返回null, null意味着没有其他的数据要读取了.
     * 每一行将会追加到StringBuilder的末尾, StringBuilder将作为String返回。
     *
     */
    public static String convertStreamToString (InputStream is)
    {		try {
		    	if (is != null) {
		            StringBuilder sb = new StringBuilder();
		            String line;
		            try {
		          	  BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); 
		          	  while ((line = reader.readLine()) != null) {
			            		  sb.append(line).append("\n") ; 
		          	  }
		            } finally { is.close();}return sb.toString();
			  	 } else { 
			  		 return "";
			  	 }
			} catch (IOException e) {
				// TODO: handle exception
				return "";
			}
    		
    }

    /**
     * 提交数据到服务器
     * @param path 上传路径(注：避免使用localhost或127.0.0.1这样的路径测试，因为它会指向手机模拟器，你可以使用http://www.itcast.cn或http://192.168.1.10:8080这样的路径测试)
     * @param params 请求参数 key为参数名,value为参数值
     * @param file 上传文件
     */
    public String post(String path, Map<String, String> params, FormFile file) throws Exception{
       return post(path, params, new FormFile[]{file});
    }
	public Handler getHandler() {
		return handler;
	}
	public void setHandler(Handler handler) {
		this.handler = handler;
	}
	public int getAlreadyUploaded() {
		return alreadyUploaded;
	}
	public void setAlreadyUploaded(int alreadyUploaded) {
		this.alreadyUploaded = alreadyUploaded;
	}
	public int getTotalFileSize() {
		return totalFileSize;
	}
	public void setTotalFileSize(int totalFileSize) {
		this.totalFileSize = totalFileSize;
	}
    
    
}